package com.yc.sole.system.repository;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.text.CharSequenceUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yc.sole.common.constant.CacheConstant;
import com.yc.sole.common.enums.CommonState;
import com.yc.sole.framework.exception.BaseException;
import com.yc.sole.framework.mybatis.page.Paging;
import com.yc.sole.framework.mybatis.util.PageUtil;
import com.yc.sole.framework.redis.RedissonService;
import com.yc.sole.framework.redis.enums.CacheTime;
import com.yc.sole.system.dto.DictDto;
import com.yc.sole.system.dto.DictItemDto;
import com.yc.sole.system.entity.DictItem;
import com.yc.sole.system.exception.SysResultEnum;
import com.yc.sole.system.mapper.DictItemMapper;
import com.yc.sole.system.request.DictItemQueryReq;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Collection;
import java.util.List;
import java.util.Objects;

/**
 * 服务接口实现
 *
 * @author yizuomin
 * @date 2023-03-26
 **/
@Slf4j
@Service
@RequiredArgsConstructor
public class DictItemRepository extends ServiceImpl<DictItemMapper, DictItem> {

    private final RedissonService redissonService;
    private final DictRepository dictRepository;

    /**
     * 新增
     *
     * @param dictItemDto
     * @return RestResult
     */
    @Transactional(rollbackFor = Exception.class)
    public void saveDictItem(DictItemDto dictItemDto) {
        DictItem entity = new DictItem();
        BeanUtil.copyProperties(dictItemDto, entity);
        this.save(entity);
        redissonService.hRemoveAll(CacheConstant.DICT_CACHE_MAP);
    }

    /**
     * 通过Id修改
     *
     * @param dictItemDto
     * @return RestResult
     */
    @Transactional(rollbackFor = Exception.class)
    public void updateDictItemById(DictItemDto dictItemDto) {
        DictItem entity = new DictItem();
        BeanUtil.copyProperties(dictItemDto, entity);
        this.updateById(entity);
        redissonService.hRemoveAll(CacheConstant.DICT_CACHE_MAP);
    }

    /**
     * 通过id删除
     *
     * @param ids
     * @return RestResult
     */
    @Transactional(rollbackFor = Exception.class)
    public void deleteDictItemByIds(Collection<Long> ids) {
        this.removeBatchByIds(ids);
        redissonService.hRemoveAll(CacheConstant.DICT_CACHE_MAP);
    }

    /**
     * 通过dictId批量删除
     *
     * @param dictIds
     * @return RestResult
     */
    @Transactional(rollbackFor = Exception.class)
    public void deleteDictItemByDictIds(Collection<Long> dictIds) {
        this.remove(Wrappers.<DictItem>lambdaQuery().in(DictItem::getDictId, dictIds));
        redissonService.hRemoveAll(CacheConstant.DICT_CACHE_MAP);
    }

    /**
     * 查询所有字典项
     *
     * @return
     */
    public List<DictItemDto> selectAllDictItem() {
        LambdaQueryWrapper<DictItem> wrapper = Wrappers.<DictItem>lambdaQuery().eq(DictItem::getState, CommonState.ENABLE);
        return BeanUtil.copyToList(this.list(wrapper), DictItemDto.class);
    }

    /**
     * 根据字典编码查询字典项
     *
     * @param dictKey
     * @return
     */
    public List<DictItemDto> selectDictItemByDictKey(String dictKey) {
        return redissonService.hCache(CacheConstant.DICT_CACHE_MAP, dictKey, CacheTime.ONE_DAY, () -> {
            DictDto dictDto = dictRepository.selectDictByKey(dictKey);
            if (Objects.isNull(dictDto)) {
                throw new BaseException(SysResultEnum.DICT_IS_NULL);
            }
            LambdaQueryWrapper<DictItem> wrapper = Wrappers.<DictItem>lambdaQuery()
                    .select(DictItem::getItemKey, DictItem::getItemName)
                    .eq(DictItem::getDictId, dictDto.getId())
                    .eq(DictItem::getState, CommonState.ENABLE)
                    .orderByAsc(DictItem::getSort);
            return BeanUtil.copyToList(this.list(wrapper), DictItemDto.class);
        });
    }

    /**
     * 分页查询
     *
     * @param page
     * @return RestResult
     */
    public Paging<DictItemDto> selectDictItemPage(Paging page, DictItemQueryReq dictItemQueryReq) {
        LambdaQueryWrapper<DictItem> queryWrapper = new QueryWrapper<DictItem>().lambda()
                .eq(DictItem::getDictId, dictItemQueryReq.getDictId())
                .eq(CharSequenceUtil.isNotBlank(dictItemQueryReq.getItemKey()), DictItem::getItemKey, dictItemQueryReq.getItemKey())
                .eq(Objects.nonNull(dictItemQueryReq.getState()), DictItem::getState, dictItemQueryReq.getState()).
                eq(CharSequenceUtil.isNotBlank(dictItemQueryReq.getItemName()), DictItem::getItemName, dictItemQueryReq.getItemName())
                .orderByAsc(DictItem::getSort)
                .orderByDesc(DictItem::getId);
        return PageUtil.pageCopy(this.page(PageUtil.toMybatisPage(page), queryWrapper), DictItemDto.class);
    }

    /**
     * 根据id查询
     *
     * @param id
     * @return
     */
    public DictItemDto selectDictItemById(Long id) {
        return BeanUtil.copyProperties(this.getById(id), DictItemDto.class);
    }
}
